package com.it.controller;

import com.it.pojo.Person;
import com.it.pojo.User;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;

import java.util.List;
// TODO SpringMVC (2)、接收请求参数说明

/*
 * 【说明】：接收参数有俩种方式：param、JSON
 *          参数编码：param：编译为ASCII码，如果有空格会将空格编译为%20 例如：name=john%20doe
 *                  JSON：编码为 UTF-8
 *          参数顺序：param 类型的参数没有顺序限制
 *                  JSON 类型的参数是有序的，采用键值对的形式进行传递，其中键值对是有序排列的
 *          参数数据类型
 *                  param：只能传递字符串
 *                  JSON：可以任意类型、例如数组，对象，字符串等
 *          参数嵌套性：
 *                  param：传递的参数不支持嵌套
 *                  JSON：支持传递的参数进行嵌套
 *          请求方式
 *                  param：采用GET请求方式
 *                  JSON：必须是POST请求方式
 * 【总结】：param：适合传递一些简单的数据、JSON：适合传递一些更为复杂，嵌套结构的数据
 * 【参数接收】：
 *          直接接收
 *                  可以直接在方法形参列表中接收，缺点是传递的参数名和形参列表名相同才会接收
 *                  如果不同就无法接收
 *          路径传参：SpringMVC提供了 @PathVariable 注解来处理路径传递参数
 *
 *          @RequestParam 注解接收
 *                   可以指定参数名
 *                   要求请求参数必须传递
 *                   为请求参数提供默认值
 */
// @EnableWebMvc // 在类上 handlerAdapter 配置JSON转换器
@Controller
@RequestMapping("/param")
@ResponseBody
public class springmvc02 {
    /**
     * TODO 直接接收
     * 【地址值】：/param/data?name=root&age=20
     * 【要求】：1、请求参数名必须与形参列表的参数名相同
     *         2、可以不传递参数
     */
    @GetMapping("/data")
    public String data(String name, int age) {
        System.out.println("name=" + name + " age=" + age);
        return "name=" + name + " age=" + age;
    }



    /**
     * TODO 注解接收
     * 【地址值】：/param/data1?account=1&page=10
     *          account必须传递、page可以不传递，给与默认值：10
     * 【要求】：指定任意的请求参数名
     *         1、要求必须传递
     *         2、要求不必须传递参数、给与一个默认值
     * 【语法】:只加在形参列表，用于指定参数名，设置是否必传参数，如果不传递参数给予默认值
     *        @RequestParam(value="参数名")：可以指定参数名，如果请求参数名和形参参数名一致、可以省略
     *        @RequestParam(required=true)：是否必须传递参数值，默认必传（true）
     *        @RequestParam(required = false,defaultValue = "10")：如果为false 必须给一个默认值
     */
    @GetMapping("/data1")
    public String data1(
            @RequestParam(value = "account", required = true) String account,
            @RequestParam(required = false, defaultValue = "10") int page
    ) {
        System.out.println("account：" + account + " page：" + page);
        return "account=" + account + " page=" + page;
    }



    /*
     * TODO 特殊值：一名多值
     * 【地址值】：/param/data2?key=1&key=2
     * 【要求】：直接使用集合接收参数、必须加@RequestParam
     */
    @GetMapping("/data2")
    public String data2(@RequestParam List<String> key) {
        System.out.println(key);
        return "ko";
    }



    /**
     * TODO 特殊值：使用实体类对象接值：
     * 【地址值】：/param/data3?username=admin&passwrod=123456
     * 【要求】：实体类的参数必须与传递的参数一致
     */
    @GetMapping("/data3")
    public String data3(User user) {
        System.out.println(user);
        return user.toString();
    }



    // TODO 路径传参：动态路径
    /**
     * 【地址值】：/param/data4/1/10
     * 【语法】：{参数1}
     * 【要求】：@PathVariable指定接收路径参数
     *
     * @PathVariable(name="account")：表示接受指定的参数
     * @PathVariable(required=false)：表示是否必传
     */
    @GetMapping("/data4/{account}/{page}")
    public String data4(@PathVariable int account, @PathVariable int page) {
        System.out.println("account=" + account + "page=" + page);
        return "account=" + account + "page=" + page;
    }



    // TODO JSON
    /**
     * 【地址值】：http://localhost:8080/param/data5
     *          { "name":"zhangsan", "age":18, "sex":"男" }
     * 【注意】：Java原生只支持路径参数和param参数，不支持JSON，因为JSON本身不是Java格式
     * 【解决】：1、需要导入JSON处理依赖 2、使用@EnableWebMvc注解 给 handlerAdapter配置JSON转换器
     * 【导入依赖】：jackson-databind
     * 【语法】：1、声明对应的实体类 2、在形参列表添加@RequestBody注解
     *         3、在导入jackson-databind依赖 4、在配置类上添加@EnableWebMvc给handlerAdapter配置JSON转换器
     */
    @PostMapping("/data5")
    public String data5(@RequestBody Person person) {
        System.out.println(person);
        return person.toString();
    }

}
